﻿using CommandService;
using Entity.FrameEntity;
using Entity;
using SysFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Net.Http.Headers;
using Newtonsoft.Json.Linq;
using System.Data;
using System.Text.RegularExpressions;

namespace BLL
{
    /// <summary>
    /// 绩效版块业务(dai)
    /// </summary>
    public class WageBLL : PubMethod
    {
        ReturnResult rsl;
        Commands cmd;
        OperateModel oper;
        List<OperateModel> operList;
        public WageBLL()
        {
            rsl = new ReturnResult();
            cmd = new Commands();
            oper = new OperateModel();
            operList = new List<OperateModel>();
        }
        /// <summary>
        /// 绩效公式(分页)
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="pageCount"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public ReturnResult FomulaList(string pageIndex, string pageSize, string condition, ref string pageCount)
        {
            rsl = new ReturnResult();
            try
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(" isdel=0 ");
                sb = CreateSelectCondition(sb, condition);
                var list = cmd.PageList("V_WageFomula_list", pageIndex, pageSize, sb.ToString(), "id desc", ref pageCount);
                rsl.Data = list;
                rsl.Result = true;
            }
            catch (Exception ex)
            {
                rsl.Message = ex.Message;
            }
            return rsl;
        }

        /// <summary>
        /// 工序绩效列表(分页)
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="pageCount"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public ReturnResult GongXuFomulaList(string pageIndex, string pageSize, string condition, ref string pageCount)
        {
            rsl = new ReturnResult();
            try
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(" isdel=0 ");
                sb = CreateSelectCondition(sb, condition);
                var list = cmd.PageList("V_WageGongXu_list", pageIndex, pageSize, sb.ToString(), "id desc", ref pageCount);
                rsl.Data = list;
                rsl.Result = true;
            }
            catch (Exception ex)
            {
                rsl.Message = ex.Message;
            }
            return rsl;
        }
        /// <summary>
        /// 绩效公式方法
        /// </summary>
        /// <param name="data"></param>
        /// <param name="userCode"></param>
        /// <returns></returns>
        public ReturnResult UpdateFormula(string data,string userCode)
        {
            rsl = new ReturnResult();
            try
            {
                var entity = JsonConvert.DeserializeObject<DbWageFormula>(data);
                if (string.IsNullOrWhiteSpace(entity.formula))
                {
                    rsl.Message = "计算公式不能为空"; return rsl;
                }
                else
                {
                    if (!entity.formula.Contains("number"))
                    {
                        rsl.Message = "公式中缺少[number]关键字"; return rsl;
                    }
                }


                if (entity.id == null || entity.id == 0)
                {
                    #region 添加方法
                    entity.createtime = getNow();
                    entity.createuser = userCode;
                    entity.isdel = 0;
                    rsl=cmd.Add(entity);
                    #endregion
                }
                else
                {
                    #region 修改方法
                    oper = new OperateModel();
                    oper.Data = entity;
                    oper.Conditions = "id";
                    oper.Types=OperateModel.OperateType.Edit;
                    rsl = cmd.Edit(oper);
                    #endregion
                }
            }
            catch (Exception ex)
            {
                rsl.Message = ex.Message;
            }
            return rsl;
        }
        /// <summary>
        /// 根据id获取绩效公式详情
        /// </summary>
        /// <param name="dataId"></param>
        /// <returns></returns>
        public ReturnResult loadFormulaByID(string dataId)
        {
            rsl = new ReturnResult();
            try
            {
                string sql = "select * from pw_WageSet_formula where id="+dataId;
                rsl.Data = cmd.TableToDictionary(cmd.GetDataTable(sql));
                rsl.Result = true;
            }
            catch (Exception ex)
            {
                rsl.Message = ex.Message;
            }
            return rsl;
        }
        /// <summary>
        /// 删除绩效公式
        /// </summary>
        /// <param name="dataId"></param>
        /// <param name="userCode"></param>
        /// <returns></returns>
        public ReturnResult DelFormulaByID(string dataId,string userCode)
        {
            rsl = new ReturnResult();
            try
            {
                DbWageFormula obj = new DbWageFormula();
                obj.id = int.Parse(dataId);
                obj.isdel = 1;
                obj.delMsg = string.Format("{0}({1})", userCode, getNow());
                oper = new OperateModel();
                oper.Data = obj;
                oper.Conditions = "id";
                oper.Types = OperateModel.OperateType.Edit;
                rsl = cmd.Edit(oper);
            }
            catch (Exception ex)
            {
                rsl.Message = ex.Message;
            }
            return rsl;
        }
        /// <summary>
        /// 获取全部有效计算公式
        /// </summary>
        /// <returns></returns>
        public ReturnResult getFomulaInfo()
        {
            rsl = new ReturnResult();
            try
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("select * from pw_WageSet_formula ");
                sb.Append("where isdel=0");
                var table = cmd.GetDataTable(sb.ToString());
                rsl.Result = true;
                rsl.Data = cmd.TableToDictionary(table);
            }
            catch (Exception ex)
            {
                rsl.Message = ex.Message;
            }
            return rsl;
        }
        /// <summary>
        /// 工序绩效
        /// </summary>
        /// <param name="data"></param>
        /// <param name="userCode"></param>
        /// <returns></returns>
        public ReturnResult SavaGongXuWage(string data,string userCode)
        {
            rsl = new ReturnResult();
            try
            {
                var obj = JsonConvert.DeserializeObject<DbWageGongXu>(data);
                if (string.IsNullOrWhiteSpace(obj.gxCode))
                {
                    rsl.Message = "相关工序不允许为空"; return rsl;
                }
                if (obj.id == null || obj.id == 0)
                {
                    #region 添加方法
                    obj.createtime = getNow();
                    obj.createuser = userCode;
                    obj.doWage = "Y";
                    obj.isdel = 0;
                    rsl = cmd.Add(obj);
                    #endregion
                }
                else
                {
                    #region 修改方法
                    oper = new OperateModel();
                    oper.Data = obj;
                    oper.Conditions = "id";
                    oper.Types = OperateModel.OperateType.Edit;
                    rsl = cmd.Edit(oper);
                    #endregion
                }
            }
            catch (Exception ex)
            {
                rsl.Message = ex.Message;
            }
            return rsl;
        }

        /// <summary>
        /// 根据id获取绩效公式详情
        /// </summary>
        /// <param name="dataId"></param>
        /// <returns></returns>
        public ReturnResult loadGXFormulaByID(string dataId)
        {
            rsl = new ReturnResult();
            try
            {
                string sql = "select * from pw_WageSet_gongxu where id=" + dataId;
                rsl.Data = cmd.TableToDictionary(cmd.GetDataTable(sql));
                rsl.Result = true;
            }
            catch (Exception ex)
            {
                rsl.Message = ex.Message;
            }
            return rsl;
        }
        /// <summary>
        /// 是否启用绩效计算
        /// </summary>
        /// <param name="gxCode">工序</param>
        /// <returns></returns>
        public ReturnResult isDoWage(string gxCode)
        {
            rsl = new ReturnResult();
            try
            {
                if (string.IsNullOrWhiteSpace(gxCode))
                {
                    rsl.Message = "工序为空";return rsl;
                }
                StringBuilder sb = new StringBuilder();
                sb.Append("select * from pw_WageSet_gongxu where isdel=0");
                sb.Append(" and gxCode='"+gxCode+"'");
                var table = cmd.GetDataTable(sb.ToString());
                if (table.Rows.Count > 0)
                {
                    if (table.Rows[0]["doWage"].ToString() == "Y")
                    {
                        rsl.Result = true;
                    }
                    else
                    {
                        rsl.Message = "绩效计算已暂停";
                    }
                }
                else
                {
                    rsl.Message = "没有查到相关数据"; 
                }
            }
            catch (Exception ex)
            { 
            
            }
            return rsl;
        }
        /// <summary>
        /// 生产绩效
        /// </summary>
        /// <param name="barJson"></param>
        /// <returns></returns>
        public ReturnResult ProductionWage(JObject barJson,ref List<OperateModel> operList,ref string uPosition)
        {
            rsl = new ReturnResult();
            operList = new List<OperateModel>();
            try
            {
                string errMsg = ""; string machineCode = "";
                uPosition = "";
                if (barJson.Property("pUser") == null || string.IsNullOrWhiteSpace(barJson["pUsers"].ToString()))
                {
                    rsl.Message = "没有获取到生产人员信息，无法生成绩效";
                    return rsl;
                } 
                string proCode = barJson["proCode"].ToString();
                string gxCode= barJson["gxCode"].ToString();
                string plCode = barJson["plCode"].ToString();
                if (barJson.Property("machine") != null && !string.IsNullOrWhiteSpace(barJson["machine"].ToString()))
                {
                    machineCode = barJson["machine"].ToString();
                }
                string fomulaStr = this.GetFomula(gxCode,proCode,ref errMsg);
                if (string.IsNullOrWhiteSpace(fomulaStr))
                {
                    rsl.Message = errMsg;
                    return rsl;
                }
                StringBuilder sb = new StringBuilder();
                sb.Append("select * from pi_ProductionPlan_info where plCode='"+ plCode +"'");
                var planTable = cmd.GetDataTable(sb.ToString());
                DataTable upTable = new DataTable() ;//人员出勤岗位
                if (!string.IsNullOrWhiteSpace(machineCode))
                {
                    sb.Clear();
                    sb.Append("select * form fun_userWork_info where machine='" + machineCode+"'");
                    upTable = cmd.GetDataTable(sb.ToString());
                }
                var uArr = barJson["pUsers"].ToString().Split(',');
                DbEmployeeWage wage;
                foreach (string us in uArr)
                {
                    var uBar = barJson;
                    double zhanbi = 1;
                    string gangwei = "";
                    var dr = upTable.Select("userCode='"+ us +"'");
                    if (dr.Length > 0)
                    {
                        zhanbi =double.Parse(dr[0]["proportion"].ToString());
                        gangwei = dr[0]["positon"].ToString();
                    }
                    uPosition += string.Format("{0}-{1},",us,gangwei);
                    uBar["number"]=zhanbi* double.Parse(uBar["number"].ToString());
                    string w_price = this.FormatFomula(fomulaStr, uBar, planTable, ref errMsg);
                    if (string.IsNullOrWhiteSpace(w_price))
                    {
                        rsl.Message = errMsg;
                        return rsl;
                    }
                    wage = new DbEmployeeWage();
                    wage.total= w_price.ToString();
                    wage.zhanbi = zhanbi.ToString();
                    wage.yNum = barJson["number"].ToString();
                    wage.happenDate = barJson["hDate"].ToString();
                    wage.createtime=getNow();
                    wage.userCode = us;
                    wage.uPrice =Math.Round(double.Parse(w_price) / double.Parse(barJson["number"].ToString()),2).ToString();
                    wage.barCode = barJson["barCode"].ToString();
                    wage.gangwei = gangwei;
                    wage.gxCode = gxCode;
                    wage.status = "approving";//
                    wage.createuser = barJson["userCode"].ToString();
                    oper = new OperateModel();
                    oper.Data = wage;
                    oper.Types = OperateModel.OperateType.Add;
                    operList.Add(oper);
                }
                uPosition = uPosition.TrimEnd(';');
             
              
            }
            catch (Exception ex)
            {
                rsl.Message = ex.Message;
            }
            return rsl;
        }
        /// <summary>
        /// 获取计算公式
        /// </summary>
        /// <param name="gxCode">工序编码</param>
        /// <param name="proCode">存货编码</param>
        /// <param name="errMsg">错误消息</param>
        /// <returns></returns>
        private string GetFomula(string gxCode,string proCode,ref string errMsg)
        {
            try
            {
                StringBuilder sb = new StringBuilder();
                string fomulaStr = "";
                sb.Append("select gsType,isnull(relationCode,'') relationCode,formula from pw_WageSet_formula ");
                sb.Append("where id in(select proFomula from pw_WageSet_gongxu where gxCode='" + gxCode+"')");
                var table = cmd.GetDataTable(sb.ToString());
                if (table.Rows.Count < 1   || string.IsNullOrWhiteSpace(table.Rows[0]["formula"].ToString()))
                {
                    errMsg = "没有获取到相关信息";
                    return fomulaStr;
                }
                var dr = table.Select("gsType='qpro'");
                if (dr.Length > 0)
                {
                    #region 存货绩效
                    if (!string.IsNullOrWhiteSpace(dr[0]["relationCode"].ToString()) || !string.IsNullOrWhiteSpace(dr[0]["formula"].ToString()))
                    {
                        var proArr = dr[0]["relationCode"].ToString().Split(',');
                        foreach (string pro in proArr)
                        {
                            if (!string.IsNullOrWhiteSpace(pro))
                            {
                                if (pro == proCode)
                                {
                                    fomulaStr = dr[0]["formula"].ToString();
                                    break;
                                }
                            }
                        }
                    }
                   

                  
                    #endregion
                }
                if (string.IsNullOrWhiteSpace(fomulaStr))
                {
                    #region 存货大类

                    #region 根据存货编码获取存货大类
                    sb.Clear();
                    sb.Append("select top 1 typeCode from fun_Inventory_Info where proCode='"+proCode+"'");
                    var proTable = cmd.GetDataTable(sb.ToString());
                    if (proTable.Rows.Count < 1)
                    {
                        errMsg = "存货编码错误";return fomulaStr;
                    }
                    string proType = proTable.Rows[0][0].ToString();
                    #endregion

                    dr = table.Select("gsType='qtype'");
                    foreach (DataRow r in dr)
                    {
                        if (!string.IsNullOrWhiteSpace(r["relationCode"].ToString()) || !string.IsNullOrWhiteSpace(r["formula"].ToString()))
                        {
                            var tArr = r["relationCode"].ToString().Split(',');
                            foreach (string f in tArr)
                            {
                                if (!string.IsNullOrWhiteSpace(f))
                                {
                                    if (f == proType)
                                    {
                                        fomulaStr = r["formula"].ToString();break;
                                    }
                                }
                            }
                            if (!string.IsNullOrWhiteSpace(fomulaStr))
                            {
                                break;
                            }
                        }
                    }
                    #endregion
                }
                if (string.IsNullOrWhiteSpace(fomulaStr))
                {
                    errMsg = "预设存货信息错误";
                    return "";
                }
                else
                {
                    return fomulaStr;
                }
            }
            catch (Exception ex)
            {
                errMsg = ex.Message;
            }
            return "";
        }
        /// <summary>
        /// 绩效金额计算方法
        /// </summary>
        /// <param name="fomulaStr">绩效计算公式</param>
        /// <param name="barJson">条码对象</param>
        /// <param name="planTable">计划数据信息表</param>
        /// <param name="errMsg"></param>
        /// <returns></returns>
        private string FormatFomula( string fomulaStr,JObject barJson, DataTable planTable,  ref string errMsg)
        {
            StringBuilder sb = new StringBuilder();
            string wageMoney = "";

            fomulaStr = fomulaStr.Replace("（", "(").Replace("）", ")");
            string newGs = fomulaStr.Replace("[", "").Replace("]", "");

            Regex reg = new Regex(@"\[(\w+)\]");
            MatchCollection mc = reg.Matches(fomulaStr);
            foreach (Match m in mc)
            {
                if (!string.IsNullOrWhiteSpace(m.Value))
                {
                    string fieldName = m.Value.Trim();//字段名称
                    fieldName = fieldName.Replace("[", "").Replace("]", "");
                    string fieldValue = "";//字段值
                    #region 获取计划获取生产值关联字段值
                    if (barJson == null || barJson.Property(fieldName) == null)
                    {
                        #region 计划主信息取数
                        if (planTable.Columns.Contains(fieldName) && planTable.Rows[0][fieldName] != null)
                        {
                            fieldValue = planTable.Rows[0][fieldName].ToString();
                        }
                        #endregion
                    }
                    else
                    {
                        fieldValue = barJson[fieldName].ToString();//生产工序表单根据字段取值
                    }
                    if (string.IsNullOrWhiteSpace(fieldValue))
                    {
                        errMsg = "字段值无法获取数值：" + fieldName;
                        return wageMoney;
                    }
                    #endregion
                    newGs = newGs.Replace(fieldName, fieldValue);
                }
            }
            if (!string.IsNullOrWhiteSpace(newGs))
            {
                var u_value = new DataTable().Compute(newGs, "").ToString();
                float wfd = 1;
                if (planTable.Columns.Contains("wageFd") && planTable.Rows[0]["wageFd"] != null && !string.IsNullOrWhiteSpace(planTable.Rows[0]["wageFd"].ToString()))
                {
                    wfd = float.Parse(planTable.Rows[0]["wageFd"].ToString());
                }
                wageMoney = (float.Parse(u_value)*wfd).ToString();
            }
            return wageMoney;
        }
    }
}
